from math import log

def createDataSet():
    dataSet = [[1,1,'yes'],
               [1,1,'yes'],
               [1,0,'no'],
               [0,1,'no'],
               [0,1,'no']]
    labels = ['no surfaceing','flippers']
    return dataSet,labels;

def calcShannonEnt(dataSet):
    """
    计算给定数据集的熵 H= -∑p(x)log2p(x)
    :return:
    """
    numEntries = len(dataSet)
    print(numEntries)
    labelCounts = {}
    #为所有可能类创建字典
    for featVec in dataSet:
        #print(featVec[-1])
        currentLabel = featVec[-1]# 数组的最后一个值 yes  no
        """
        dict_keys([])
        dict_keys(['yes'])
        dict_keys(['yes'])
        dict_keys(['yes', 'no'])
        dict_keys(['yes', 'no'])
        """
        print(labelCounts.keys())
        if currentLabel not in labelCounts.keys():labelCounts[currentLabel]=0 # 如果当前不存在 则设置数据为0  否则+1
        labelCounts[currentLabel]+=1
    print(labelCounts) #{'yes': 2, 'no': 3}
    shannonEnt = 0.0
    for key in labelCounts:
        prob = float(labelCounts[key])/numEntries # 计算概率
        shannonEnt -= prob*log(prob,2) #求对数
        """
        0.5287712379549449
        0.9709505944546686
        """
        print(shannonEnt)
    return shannonEnt


def splitDataSet(dataSet ,axis,value):
    """
    遍历数据集中的每个元素，一旦发现符合要求的值，则将其添加到新创建的列表中
    :param dataSet: 待划分的数据集
    :param axis: 划分数据集的特征
    :param value: 需要返回的特征的值
    :return:
    """
    retDataSet = [] # 创建新的list对象
    for featVec in dataSet: #抽取数据
        if featVec[axis] == value:
            reducedFeatVec = featVec[:axis]
            reducedFeatVec.extend(featVec[axis+1:])
            retDataSet.append(reducedFeatVec)
    return retDataSet;


if __name__ == '__main__':
    dataSet, labels = createDataSet()
    calcShannonEnt(dataSet)